<?php

namespace common\service;

use common\model\TenantAuthenticationModel;
use common\model\TenantGroupApplyModel;
use common\model\TenantGroupMemberModel;
use common\model\TenantGroupModel;
use common\model\TenantModel;
use support\ErrorCode;
use teamones\Request;

class TenantGroupService
{
    /**
     * @var object|\think\Model|\think\model\RelationModel
     */
    private $tenantGroupModel;

    public function __construct()
    {
        $this->tenantGroupModel = model(TenantGroupModel::class);
    }

    /**
     * 获取集团列表
     * @param $param
     * @param $tenantId
     * @return array
     */
    public function select($param, $tenantId)
    {
        $tenantGroupQuery = $this->tenantGroupModel;
        $where = $param['filter'] ?? [];

        $tenantGroupList['total'] = $tenantGroupQuery->where($where)->count();

        if (array_key_exists('order', $param)) {
            $tenantGroupQuery->order($param['order']);
        }

        $page = $param['page'] ?? [1, C("database.database_max_select_rows")];
        $tenantGroupList['rows'] = $tenantGroupQuery->where($where)->page(...$page)->select();
        $tenantGroupIds = array_column($tenantGroupList['rows'], 'id');
        // 查找集团是否申请
        $tenantGroupApplyModel = model(TenantGroupApplyModel::class);
        $tenantGroupApplyList = $tenantGroupApplyModel->where(['tenant_id' => $tenantId, 'tenant_group_id' => ['IN', implode(',', $tenantGroupIds)]])->select();
        $tenantGroupApplyMap = array_column($tenantGroupApplyList, null, 'tenant_group_id');
        // 查找集团下的成员是否还存在该公司
        $tenantGroupMemberModel = model(TenantGroupMemberModel::class);
        $tenantGroupMemberList = $tenantGroupMemberModel->where(['tenant_group_id' => ['IN', implode(',', $tenantGroupIds)], 'tenant_id' => $tenantId])->select();
        $tenantGroupMemberIds = array_column($tenantGroupMemberList, 'tenant_group_id');
        // 查找集团的所属租户
        $tenantModel = model(TenantModel::class);
        $tenantIds = array_column($tenantGroupList['rows'], 'tenant_id');
        $tenantList = $tenantModel->field('id,name')->where(['id' => ['In', implode(',', $tenantIds)]])->select();
        $tenantList = array_column($tenantList, 'name', 'id');
        foreach ($tenantGroupList['rows'] as &$item) {
            $item['tenant_name'] = $tenantList[$item['tenant_id']];
            $item['is_apply'] = false;
            if ($item['tenant_id'] != $tenantId) {
                $item['is_apply'] = in_array($item['id'], $tenantGroupMemberIds) || !empty($tenantGroupApplyMap[$item['id']]) && $tenantGroupApplyMap[$item['id']]['status'] == 'applying';
            } else {
                $item['is_apply'] = true;
            }
        }
        return $tenantGroupList;
    }

    /**
     * 当前租户查找所有集团
     * @param $tenantId
     * @return array|false|mixed|string|void
     */
    public function selectCurrentTenantGroup($tenantId)
    {
        $options = [
            'filter' => ['tenant_id' => ['EQ', $tenantId]]
        ];
        $tenantGroupMemberModel = model(TenantGroupMemberModel::class);
        $tenantGroupMemberList = $tenantGroupMemberModel->where($options['filter'])->select();
        if ($tenantGroupMemberList) {
            $tenantGroupIds = array_column($tenantGroupMemberList, 'tenant_group_id');
            $tenantGroupList = $this->tenantGroupModel->where(['id' => ['In', implode(',', $tenantGroupIds)]])->select();
            $tenantGroupIds = array_column($tenantGroupList, 'id');
            // 查找有订单的集团
            $tenantGroupOrderList = $this->selectTenantGroupOrder(implode(',', $tenantGroupIds));
            $tenantGroupOrderIds = array_column($tenantGroupOrderList['rows'], 'tenant_group_id');
            foreach ($tenantGroupList as &$item) {
                $item['is_dissolve'] = true;
                if (in_array($item['id'], $tenantGroupOrderIds)) {
                    $item['is_dissolve'] = false;
                }
            }
            return $tenantGroupList;
        } else {
            return [];
        }
    }

    /**
     * 新增集团
     * @param $data
     * @param $tenantId
     * @param $userId
     * @return bool
     * @throws \Throwable
     */
    public function create($data, $tenantId, $userId)
    {
        //判断集团名是否重复
        $info = $this->tenantGroupModel->where(['tenant_id' => $tenantId, 'name'=>$data['name']])->find();
        if ($info) {
            throw_strack_exception('Param error', ErrorCode::REQUEST_PARAM_ERROR);
        }

        $tenantGroupData = $data;
        $tenantGroupData['tenant_id'] = $tenantId;
        $tenantGroupData['created_by'] = $userId;
        $this->tenantGroupModel->startTrans();
        try {
            $resTenantGroupSave = $this->tenantGroupModel->addItem($tenantGroupData);
            $tenantMemberData = [];
            $tenantMember = model(TenantGroupMemberModel::class);
            $tenantMemberData['tenant_id'] = $tenantId;
            $tenantMemberData['created_by'] = $userId;
            $tenantMemberData['tenant_group_id'] = $resTenantGroupSave['id'];
            $tenantMember->addItem($tenantMemberData);
            return $this->tenantGroupModel->commit();
        } catch (\Throwable $e) {
            $this->tenantGroupModel->rollback();
            throw $e;
        }
    }

    /**
     *  更新集团
     */
    public function update(array $data, int $tenantId)
    {
        //检查数据
        $this->checkTenantGroupData($data, $tenantId);
        return model(TenantGroupModel::class)->modifyItem($data);
    }

    /**
     * 检查集团数据
     * @param int   $tenantId 租户ID
     * @param array $data 数据
     * @return void
     */
    private function checkTenantGroupData(array $data, int $tenantId)
    {
        $id = $data['id'] ?? 0;
        //判断是否有权限修改
        $info = model(TenantGroupModel::class)->where(['tenant_id' => $tenantId, 'id'=>$id])->find();
        if (empty($info)) {
            throw_strack_exception('Param error', ErrorCode::REQUEST_PARAM_ERROR);
        }

        //集团名列表
        $list = model(TenantGroupModel::class)->field('id,name,project_ids')->where(['tenant_id' => $tenantId])->select();
        $nameList = $projectIdList = [];
        foreach ($list as $val) {
            if ($id != $val['id']) {
                $nameList[] = $val['name'];
                $projectIds = explode(',', $val['project_ids']);
                $projectIdList = array_merge($projectIdList, $projectIds);
            }
        }
        //判断集团名是否重复
        if (isset($data['name']) && in_array($data['name'], $nameList)) {
            throw_strack_exception('Duplicate group name', ErrorCode::DUPLICATE_GROUP_NAME);
        }
        //判断集团--项目是否存在
        if (isset($data['project_ids'])) {
            $projectList = explode(',', $data['project_ids']);
            foreach ($projectList as $projectId) {
                if ($projectId && in_array($projectId, $projectIdList)) {
                    throw_strack_exception('The group project already exists', ErrorCode::GROUP_PROJECT_IS_EXIT);
                }
            }
        }
    }

    /**
     * 转让集团
     * @param $data
     * @param $tenantId
     * @return bool|float|int|string|void
     * @throws \Exception
     */
    public function transfer($data, $tenantId)
    {
        $tenantGroup = $this->tenantGroupModel->find($data['id']);
        if ($tenantGroup['tenant_id'] != $tenantId) {
            throw_strack_exception('Tenant Not Permission', ErrorCode::TENANT_NOT_PERMISSION);
        }
        $tenantGroupMemberModel = model(TenantGroupMemberModel::class);
        $tenantGroupMemberExists = $tenantGroupMemberModel->where(['tenant_group_id' => $data['id'], 'tenant_id' => $data['tenant_id']])->find();
        // 必须是在当前集团的成员下才能转让
        if (empty($tenantGroupMemberExists)) {
            throw_strack_exception('The tenant already not exists', ErrorCode::TENANT_MEMBER_NOT_EXISTS);
        }
        $tenant = model(TenantModel::class);
        $tenantData = $tenant->where(['id' => $data['tenant_id'], 'status' => 'active'])->find();
        if (empty($tenantData)) {
            throw_strack_exception('Tenant Not Found', ErrorCode::TENANT_NOT_EXIST);
        }
        $tenantAuth = model(TenantAuthenticationModel::class);
        $tenantAuthData = $tenantAuth->where(['tenant_id' => $data['tenant_id']])->find();
        if (empty($tenantAuthData) || $tenantAuthData['status'] != "active") {
            throw_strack_exception('Tenant Not Auth', ErrorCode::TENANT_AUTHENTICATION_FAILED);
        }
        return $this->tenantGroupModel->save($data);
    }

    /**
     * 解散集团
     * @param $data
     * @param $tenantId
     * @return bool
     * @throws \Throwable
     */
    public function dissolve($data, $tenantId)
    {
        $tenantGroupModel = model(TenantGroupModel::class);
        $tenantGroupData = $tenantGroupModel->find($data['tenant_group_id']);
        if (empty($tenantGroupData)) {
            throw_strack_exception('TenantGroup Not Exists', ErrorCode::TENANT_GROUP_NOT_EXIST);
        }
        if ($tenantGroupData['tenant_id'] != $tenantId) {
            throw_strack_exception('Tenant Not Permission', ErrorCode::TENANT_NOT_PERMISSION);
        }
        $tenantGroupOrderList = $this->selectTenantGroupOrder($tenantGroupData['id']);
        if ($tenantGroupOrderList['rows']) {
            throw_strack_exception('The group has unfinished business', ErrorCode::TENANT_GROUP_TASK_NOT_FINISH);
        }
        $tenantGroupMemberModel = model(TenantGroupMemberModel::class);
        $tenantGroupMember = $tenantGroupMemberModel->where(['tenant_group_id' => $tenantGroupData['id']])->select();
        $tenantGroupModel->startTrans();
        try {
            if ($tenantGroupMember) {
                $tenantGroupMemberIds = array_column($tenantGroupMember, 'id');
                $tenantGroupMemberModel->where(['id' => ['IN', implode(',', $tenantGroupMemberIds)]])->delete();
            }
            $tenantGroupModel->where(['id' => $tenantGroupData['id']])->delete();
            return $tenantGroupModel->commit();
        } catch (\Throwable $e) {
            $tenantGroupModel->rollback();
            throw $e;
        }
    }

    /**
     * 查找集团订单
     * @param $tenantGroupIds
     * @return mixed
     */
    private function selectTenantGroupOrder($tenantGroupIds)
    {
        return Request::connection()
            ->setHeader([
                'X-Userinfo' => request()->getXUserInfo(),
            ])
            ->setServerHost('teamones-saas')
            ->setRoute('order/select')
            ->setBody([
                'param' => [
                    'filter' => [
                        'tenant_group_id' => ['-in', $tenantGroupIds],
                        "type" => "tenant_group",
                        'status' => ['-in', 'inprogress,wait_for_add_settlement,wait_for_review_settlement,wait_for_settlement,done']
                    ]
                ]
            ])
            ->setMethod('POST')
            ->request()['data'];
    }

    /**
     * 查找租户订单完成数
     * @param $tenantGroupIds
     * @return mixed
     */
    public function getTenantOrderDoneNum($tenantGroupIds)
    {
        return Request::connection()
            ->setHeader([
                'X-Userinfo' => request()->getXUserInfo(),
            ])
            ->setServerHost('teamones-saas')
            ->setRoute('supplier/get_order_done_num')
            ->setBody([
                'param' => [
                    'filter' => [
                        'from_tenant_id' => ['-in', $tenantGroupIds],
                        'type' => 'outside'
                    ]
                ]
            ])
            ->setMethod('POST')
            ->request()['data'];
    }
}